using UnityEngine;
using System.Linq;
using System.Collections;

public class Player : MonoBehaviour
{
    public Transform enemy;
    [Header("移动速度")]
    public float Speed = 5f;
    [Header("攻击范围")]
    public float AttackRange = 2f;
    [Header("攻击力")]
    public float Atk = 20f;
    [Header("攻击间隔 单位:秒")]
    public float AttackCD = 1f;
    // [Header("视野范围")]
    // public float VisionRange = 5f;
    [Header("与敌人保持的距离范围")]
    // 在这个范围内会攻击敌人 太近会主动远离敌人 太远会主动拉近敌人
    public float MinDistenceRange = 1f;
    public float MaxDistenceRange = 1.5f;
    // 记录上次攻击距离现在的时间
    private float lastAttackTime = 0f;
    public Animator animator;
    public GameController gameController;
    public bool IsBeingAttacked = false;

    // 固定时长飞行相关字段
    public bool IsFlying = false;
    [Header("被击飞时飞行速度")]
    public float FlySpeed = 10f;
    private Vector3 _flyStartPos;
    private Vector3 _flyTargetPos;
    [SerializeField]
    private float _flyDuration = 0.5f;
    private float _flyElapsed = 0f;
    // Dash相关
    public bool IsDashing = false;
    [Header("dash时飞行速度")]
    public float DashSpeed = 15f;
    public float DashCD = 4f;
    private float lastDashTime = 0f;
    private Vector3 _dashStartPos;
    private Vector3 _dashTargetPos;
    private float _dashDuration = 0.5f;
    private float _dashElapsed = 0f;
    // 击飞作用范围半径
    public float BoomR;
    void Start()
    {
        gameController = GameObject.Find("GameController").GetComponent<GameController>();
    }
    


    void Update()
    {
        if (GameManager.Instance.IsGameOver)
        {
            return;
        }
        // 计时攻击间隔
        Timer();

        // 可能会出现敌人死了但是主角仍然准备攻击敌人的情况 因此先判断是否为空
        if (enemy == null)
        {
            FindAndAttack(AttackRange);
        }

        // 处理固定时长飞行
        if (IsFlying)
        {
            _flyElapsed += Time.deltaTime;
            float t = Mathf.Clamp01(_flyElapsed / _flyDuration);
            transform.position = Vector3.Lerp(_flyStartPos, _flyTargetPos, t);
            return;
        }

        if (IsDashing)
        {
            _dashElapsed += Time.deltaTime;
            float t = Mathf.Clamp01(_dashElapsed / _dashDuration);
            transform.position = Vector3.Lerp(_dashStartPos, _dashTargetPos, t);
            return;
        }


        if (IsBeingAttacked) return;

        if (DashCD <= lastDashTime)
        {
            FindRandomEnemy();
            StartCoroutine(StartDash(enemy.transform.position, 0.2f));
            return;
        }

        FindAndAttack(AttackRange);
    }

    // 寻找最近的敌人，如果在指定范围内就攻击
    public void FindAndAttack(float attackRange)
    {
        float minDistance = FindMinDistanceEnemy();
        Move(minDistance);
        if (minDistance <= attackRange && lastAttackTime >= AttackCD)
        {
            Attack();
        }
    }
    
    public void Move(float minDistance)
    {
        // 如果已经到达了边界，就不移动了
        if (transform.position.x >= gameController.BattlefieldBorderRight ||
            transform.position.x <= gameController.BattlefieldBorderLeft ||
            transform.position.y >= gameController.BattlefieldBorderTop ||
            transform.position.y <= gameController.BattlefieldBorderBottom)
        {
            animator.SetBool("IsMoving", false);
            return;
        }
        // 策略为与敌人保持指定的距离
        if (enemy == null)
        {
            animator.SetBool("IsMoving", false);
            return;
        } else {
            if (minDistance > MaxDistenceRange)
            {
                Vector3 direction = (enemy.position - transform.position).normalized;
                transform.Translate(direction * Speed * Time.deltaTime, Space.World);
            }
            else if (minDistance < MinDistenceRange)
            {
                Vector3 direction = (transform.position - enemy.position).normalized;
                transform.Translate(direction * Speed * Time.deltaTime, Space.World);
            }
            animator.SetBool("IsMoving", true);
        }
    }

    public float FindMinDistanceEnemy()
    {
        float borderTop = gameController.BattlefieldBorderTop;
        float borderBottom = gameController.BattlefieldBorderBottom;
        float borderLeft = gameController.BattlefieldBorderLeft;
        float borderRight = gameController.BattlefieldBorderRight;
        // 寻找直线距离最近的敌人
        Enemy[] enemies = GameObject.FindGameObjectsWithTag("Enemy").Select(e => e.GetComponent<Enemy>()).ToArray();
        if (enemies.Length == 0)
        {
            enemy = null;
            return Mathf.Infinity;
        }
        float minDistance = Mathf.Infinity;
        foreach (Enemy e in enemies)
        {
            bool isOutOfRange = e.transform.position.x > borderRight || e.transform.position.x < borderLeft || e.transform.position.y > borderTop || e.transform.position.y < borderBottom;
            // Debug.Log("敌人位置: " + e.transform.position + " 是否在范围外: " + isOutOfRange);
            if (isOutOfRange)
            {
                continue;
            }
            // if (e.IsDied)
            // {
            //     continue;
            // }
            float distance = Vector3.Distance(transform.position, e.transform.position);
            // 遍历的此敌人比之前找到的最近敌人还近 且敌人在视野范围内
            if (distance < minDistance)
            {
                minDistance = distance;
                enemy = e.transform;
            }
        }
        // 正面朝向敌人
        if (enemy != null)
        {
            if (enemy.position.x - transform.position.x > 0)
            {
                ReverseSprite(1);
            }
            else
            {
                ReverseSprite(-1);
            }
        }
        return minDistance;
    }

    public void FindRandomEnemy()
    {
        var enemyGOs = GameObject.FindGameObjectsWithTag("Enemy");
        if (enemyGOs.Length == 0)
        {
            return;
        }

        // 过滤掉边界外或已死亡/无 Enemy 组件的对象
        var validEnemies = enemyGOs
            .Select(go => go.GetComponent<Enemy>())
            .Where(e => e != null
                        && e.transform.position.x <= gameController.BattlefieldBorderRight
                        && e.transform.position.x >= gameController.BattlefieldBorderLeft
                        && e.transform.position.y <= gameController.BattlefieldBorderTop
                        && e.transform.position.y >= gameController.BattlefieldBorderBottom)
            .ToArray();

        if (validEnemies.Length == 0)
        {
            return;
        }
        int rand = Random.Range(0, validEnemies.Length);
        enemy = validEnemies[rand].transform;
    }
    public void Attack()
    {
        if (enemy != null)
        {
            // if (lastAttackTime < AttackCD)
            // {
            //     return; // 攻击间隔未到，不能攻击
            // }
            Enemy enemyScript = enemy.GetComponent<Enemy>();
            // 重置攻击时间
            lastAttackTime = 0f;
            animator.SetTrigger("Attack");
            // 等待动画后再造成伤害

            StartCoroutine(enemyScript.TakeDamage(Atk, 0.3f));
        }
    }

    public IEnumerator BeAttacked()
    {
        IsBeingAttacked = true;
        // 将人机位置设置到敌人前方一点点 然后持续晃动0.5s
        for (int i = 0; i < 10; i++)
        {
            transform.position = new Vector3(
                transform.position.x,
                // i为偶数时上移一点点 奇数时下移一点点
                transform.position.y + (i % 2 == 0 ? 0.1f : -0.1f),
                transform.position.z
            );
            yield return new WaitForSeconds(0.05f);
        }
        // 随机一个范围内的坐标
        Vector3 pos = new Vector3(
            Random.Range(gameController.BattlefieldBorderLeft, gameController.BattlefieldBorderRight),
            Random.Range(gameController.BattlefieldBorderBottom, gameController.BattlefieldBorderTop),
            0
        );
        // 虫子开始飞
        yield return StartFly(pos);
        IsBeingAttacked = false;
    }

    public IEnumerator StartFly(Vector3 toPosition)
    {
        StartFlyTo(toPosition);
        animator.SetTrigger("Hit");
        yield return new WaitForSeconds(_flyDuration);
        animator.SetTrigger("HitOver");
        IsFlying = false;
    }

    // 开始一个基于距离自动计算时长的飞行动作（duration = distance / FlySpeed）
    public void StartFlyTo(Vector3 toPosition)
    {
        _flyStartPos = transform.position;
        _flyTargetPos = toPosition;
        float distance = Vector3.Distance(_flyStartPos, _flyTargetPos);
        float effectiveSpeed = Mathf.Max(0.0001f, FlySpeed);
        _flyDuration = distance / effectiveSpeed;
        _flyElapsed = 0f;
        IsFlying = true;
    }

    public IEnumerator StartDash(Vector3 toPosition, float invincibleTime = 0.3f)
    {
        Vector3 oriPlayerPos = transform.position;
        Debug.Log("dash to" + toPosition);
        StartDashTo(toPosition);
        animator.SetTrigger("Dash");
        AudioManager.Instance.PlaySFX(7);
        yield return new WaitForSeconds(_dashDuration);
        BoomEnemies(toPosition, oriPlayerPos);
        AudioManager.Instance.PlaySFX(8);
        yield return new WaitForSeconds(invincibleTime);
        IsDashing = false;
        lastDashTime = 0;
        animator.SetTrigger("DashEnd");
    }

    // 击退敌人 坐标、半径
    public void BoomEnemies(Vector3 pos, Vector3 oriPlayerPos)
    {
        // 获取目标坐标的一定范围内的所有敌人
        Enemy[] enemies = GameObject.FindGameObjectsWithTag("Enemy").Select(e => e.GetComponent<Enemy>()).ToArray();
        foreach(Enemy e in enemies)
        {
            if (Vector3.Distance(e.transform.position, pos) <= BoomR)
            {
                StartCoroutine(e.BeHitBack(oriPlayerPos));
            }
        }
    }

    public void StartDashTo(Vector3 toPosition)
    {        
        _dashStartPos = transform.position;
        _dashTargetPos = toPosition;
        float distance = Vector3.Distance(_dashStartPos, _dashTargetPos);
        float effectiveSpeed = Mathf.Max(0.0001f, DashSpeed);
        _dashDuration = distance / effectiveSpeed;
        _dashElapsed = 0f;
        IsDashing = true;
    }

    public void Wait()
    {
        // 没想好写点啥
    }

    // 翻转精灵到指定方向
    public void ReverseSprite(int direction)
    {
        Vector3 scale = transform.localScale;
        scale.x = direction;
        transform.localScale = scale;
    }
    
    private void Timer()
    {
        lastAttackTime += Time.deltaTime;
        lastDashTime += Time.deltaTime;
    }
}